use tock_registers::{
    register_bitfields, register_structs,
    registers::{ReadOnly, ReadWrite},
};

register_structs! {
    pub FCanRegs {
        /// Global control register.
        (0x00 => pub ctrl: ReadWrite<u32, CTRL::Register>),
        (0x04 => _reserved0: u32),
        /// Arbitration rate control register.
        (0x08 => pub arb_rate_ctrl: ReadWrite<u32, ARB_RATE_CTRL::Register>),
        /// Data rate control register.
        (0x0c => pub dat_rate_ctrl: ReadWrite<u32, DAT_RATE_CTRL::Register>),
        /// Acceptance identifier0 register.
        (0x10 => pub acc_id0: ReadWrite<u32>),
        (0x14 => pub acc_id1: ReadWrite<u32>),
        (0x18 => pub acc_id2: ReadWrite<u32>),
        (0x1c => pub acc_id3: ReadWrite<u32>),
        /// Acceptance identifier0 mask register.
        (0x20 => pub acc_id0_mask: ReadWrite<u32>),
        (0x24 => pub acc_id1_mask: ReadWrite<u32>),
        (0x28 => pub acc_id2_mask: ReadWrite<u32>),
        (0x2c => pub acc_id3_mask: ReadWrite<u32>),
        /// Transfer status register.
        (0x30 => pub xfer_sts: ReadOnly<u32>),
        /// Error counter register.
        (0x34 => pub err_cnt: ReadOnly<u32>),
        /// FIFO counter register.
        (0x38 => pub fifo_cnt: ReadOnly<u32, FIFO_CNT::Register>),
        /// DMA request control register.
        (0x3c => pub dma_ctrl: ReadWrite<u32>),
        /// Transfer enable register.
        (0x40 => pub xfer_en: ReadWrite<u32>),
        (0x44 => _reserved1: u32),
        /// Frame valid number register.
        (0x48 => pub frm_info: ReadOnly<u32>),
        (0x4c => pub _reserved2: [u8; 180]),
        /// TX FIFO shadow register.
        (0x100 => pub tx_fifo: ReadWrite<u32>),
        (0x104 => pub _reserved3: [u8; 252]),
        /// RX FIFO shadow register.
        (0x200 => pub rx_fifo: ReadOnly<u32>),
        (0x204 => _reserved4: [u8; 252]),
        /// Current frame status register.
        (0x300 => pub rx_info_fifo: ReadOnly<u32>),
        (0x304 => @END),
    }
}

register_bitfields![u32,
    /// Global control register
    pub CTRL [
        /// Transfer enable
        XFER OFFSET(0) NUMBITS(1) [],
        /// Transmit request
        TXREQ OFFSET(1) NUMBITS(1) [],
        /// Acceptance identifier mask enable
        AIME OFFSET(2) NUMBITS(1) [],
        /// Soft reset (auto clear)
        RST OFFSET(7) NUMBITS(1) [],
        /// Generate frame recv completion interrupt when filtering frames
        RFEIDF OFFSET(8) NUMBITS(1) [],
        /// Generate frame recv completion interrupt when sending frame
        IRFEDT OFFSET(9) NUMBITS(1) [],
        /// Send overload frame
        IOF OFFSET(10) NUMBITS(1) [],
        /// Stuff count, CRC mode
        FDCRC OFFSET(11) NUMBITS(1) [],
    ],

    /// Arbitration rate control register
    pub ARB_RATE_CTRL [
        /// Bit rate prescaler
        BRP OFFSET(0) NUMBITS(9) [],
        /// Synchronization jump width
        SJW OFFSET(16) NUMBITS(3) [],
        /// Time segment 1
        TSEG1 OFFSET(20) NUMBITS(4) [],
        /// Time segment 2
        TSEG2 OFFSET(24) NUMBITS(3) [],
    ],

    /// Data rate control register
    pub DAT_RATE_CTRL [
        /// Data bit rate prescaler
        DBRP OFFSET(0) NUMBITS(9) [],
        /// Data synchronization jump width
        DSJW OFFSET(16) NUMBITS(3) [],
        /// Data time segment 1
        DTSEG1 OFFSET(20) NUMBITS(4) [],
        /// Data time segment 2
        DTSEG2 OFFSET(24) NUMBITS(3) [],
    ],

    /// FIFO counter register
    pub FIFO_CNT [
        /// Receive FIFO valid data number
        RFN OFFSET(0) NUMBITS(7) [],
        /// Transmit FIFO valid data number
        TFN OFFSET(16) NUMBITS(7) [],
    ],
];
